<?php

use \Common\Lib\Util\File as FileUtil;
/**
 * URL组装 支持不同URL模式
 * @param string $url URL表达式，格式：'[模块/控制器/操作#锚点@域名]?参数1=值1&参数2=值2...'
 * @param string|array $vars 传入的参数，支持数组和字符串
 * @param string $suffix 伪静态后缀，默认为true表示获取配置值
 * @param boolean $domain 是否显示域名
 * @return string
 */
function UU($url='', $vars='', $suffix=true, $domain=false) {
    $routes = get_routes();
    //dump($routes);
    if (empty($routes)) {
        //不存在路由,则直接以U方法生成
        return U($url, $vars, $suffix, $domain);
    } else {
        // 解析URL
        $info=parse_url($url);
        //如果path为空,则path为方法,否则为path
        $url= !empty($info['path']) ? $info['path'] : ACTION_NAME;
        if (isset($info['fragment'])) { // 解析锚点
            $anchor=$info['fragment'];
            //瞄点含?,则第1部分为真瞄点,第2部分为参数查询部分
            if(false !== strpos($anchor,'?')) { // 解析参数
                list($anchor,$info['query'])=explode('?',$anchor,2);
            }
            //瞄点含@,则第1部分为真瞄点,第2部分为域名host
            if(false !== strpos($anchor,'@')) { // 解析域名
                list($anchor,$host)=explode('@',$anchor, 2);
            }
        }elseif(false !== strpos($url,'@')) { // 解析域名
            //path中含@,则第1部分为真正的path,赋值给url,第2为域名
            list($url,$host)=explode('@',$info['path'], 2);
        }


        // 解析参数
        if (is_string($vars)) { // aaa=1&bbb=2 转换成数组
            parse_str($vars,$vars);
        } elseif (!is_array($vars)) {
            $vars = array();//既不是字符串,也不是数组,则为空数组
        }
        //合并参数
        if (isset($info['query'])) { // 解析地址里面参数 合并到vars
            parse_str($info['query'], $params);
            $vars = array_merge($params, $vars);
        }
        //$vars_src=$vars;
        ksort($vars);
        // URL组装
        $depr = C('URL_PATHINFO_DEPR');
        $urlCase = C('URL_CASE_INSENSITIVE');
        if('/' != $depr) { // 安全替换
            $url = str_replace('/', $depr, $url);
        }
        // 解析模块、控制器和操作
        $url        =   trim($url,$depr);
        $path       =   explode($depr,$url);
        $var        =   array();
        $varModule      =   C('VAR_MODULE');
        $varController  =   C('VAR_CONTROLLER');
        $varAction      =   C('VAR_ACTION');
        $var[$varAction]       =   !empty($path)?array_pop($path):ACTION_NAME;
        $var[$varController]   =   !empty($path)?array_pop($path):CONTROLLER_NAME;
        //处理方法映射
        if($maps = C('URL_ACTION_MAP')) {
            if(isset($maps[strtolower($var[$varController])])) {
                $maps = $maps[strtolower($var[$varController])];
                if($action = array_search(strtolower($var[$varAction]), $maps)){
                    $var[$varAction] = $action;
                }
            }
        }
        //处理控制器映射
        if($maps = C('URL_CONTROLLER_MAP')) {
            if($controller = array_search(strtolower($var[$varController]),$maps)){
                $var[$varController] = $controller;
            }
        }
        if($urlCase) {
            $var[$varController] = parse_name($var[$varController]);
        }
        $module =   '';

        if(!empty($path)) {
            $var[$varModule] = array_pop($path);
        }else{
            if(C('MULTI_MODULE')) {
                //多模块
                if(MODULE_NAME != C('DEFAULT_MODULE') || !C('MODULE_ALLOW_LIST')){
                    $var[$varModule]=   MODULE_NAME;
                }
            }
        }
        //处理模块映射
        if($maps = C('URL_MODULE_MAP')) {
            if($_module = array_search(strtolower($var[$varModule]),$maps)){
                $var[$varModule] = $_module;
            }
        }
        if(isset($var[$varModule])){
            $module =   $var[$varModule];
        }
        //开始拼装
        if (C('URL_MODEL') == 0) { // 普通模式URL转换
            $url =  __APP__ . '?' . http_build_query(array_reverse($var));
            if ($urlCase) {
                $url = strtolower($url);
            }
            if (!empty($vars)) {
                $vars   =   http_build_query($vars);
                $url   .=   '&' . $vars;
            }
        }else{ // PATHINFO模式或者兼容URL模式
            if(empty($var[$varModule])){
                $var[$varModule]=MODULE_NAME;//模块为空,则以当前模块
            }
            $module_controller_action = strtolower(implode($depr,array_reverse($var)));//拼装成"模块/控制器/方法"
            //匹配路由规则
            $has_route=false;
            //拼装成原始url,形式"模块/控制器/方法?参数1=值1&参数2=值2"
            $original_url=$module_controller_action.(empty($vars)?"":"?").http_build_query($vars);
            if (isset($routes['static'][$original_url])) {
                //存在静态路由
                $has_route = true;
                //返回静态后的url
                $url=__APP__ . "/" . $routes['static'][$original_url];
            }else{
                //不存在静态路由,则开始查找动态路由
                if(isset($routes['dynamic'][$module_controller_action])){
                    //存在
                    $urlrules=$routes['dynamic'][$module_controller_action];//所有"模块/控制器/方法"的规则
                    $empty_query_urlrule=array();
                    foreach ($urlrules as $ur){
                        $intersect=array_intersect_assoc($ur['query'], $vars);//返回键名 键值都一样的
                        if($intersect){
                            $vars=array_diff_key($vars,$ur['query']);//所有$vars参数数组不在规则参数的数组
                            $url= $ur['url'];
                            $has_route=true;
                            break;//退出循环
                        }
                        //不存在参数
                        if(empty($empty_query_urlrule) && empty($ur['query'])){
                            $empty_query_urlrule=$ur;
                        }
                    }
                    if(!empty($empty_query_urlrule)){
                        //不含参数
                        $has_route=true;
                        $url=$empty_query_urlrule['url'];
                    }
                    $new_vars=array_reverse($vars);
                    foreach ($new_vars as $key =>$value){
                        if(strpos($url, ":$key")!==false){
                            $url=str_replace(":$key", $value, $url);
                            unset($vars[$key]);
                        }
                    }
                    $url=str_replace(array("\d","$"), "", $url);
                    if($has_route){
                        if(!empty($vars)) { // 添加参数
                            foreach ($vars as $var => $val){
                                if('' !== trim($val))   $url .= $depr . $var . $depr . urlencode($val);
                            }
                        }
                        $url =__APP__."/".$url ;
                    }
                }//存在动态路由
            }
            $url=str_replace(array("^","$"), "", $url);
            //不存在路由
            if (!$has_route) {
                $module =   defined('BIND_MODULE') ? '' : $module;
                $url    =   __APP__.'/'.implode($depr,array_reverse($var));
                if($urlCase){
                    $url    =   strtolower($url);
                }
                if(!empty($vars)) { // 添加参数
                    foreach ($vars as $var => $val){
                        if ('' !== trim($val)) $url .= $depr . $var . $depr . urlencode($val);
                    }
                }
            }
            //添加静态后缀
            if ($suffix) {
                $suffix = $suffix === true?C('URL_HTML_SUFFIX'):$suffix;
                if($pos = strpos($suffix, '|')){
                    $suffix = substr($suffix, 0, $pos);
                }
                if($suffix && '/' != substr($url,-1)){
                    $url  .=  '.'.ltrim($suffix,'.');
                }
            }
        }//pathinfo或兼容模式结束
        //添加瞄点
        if (isset($anchor)) {
            $url  .= '#' . $anchor;
        }
        //添加域名
        if ($domain) {
            $url = (is_ssl()?'https://':'http://') . $domain . $url;
        }
        return $url;
    }
}

/**
 * 获取URL路由规则
 * @param boolean $refresh 是否刷新
 * @return array
 */
function x_get_routes($refresh = false) {
    $routes = F('routes');
    if ((!empty($routes)||is_array($routes)) && !$refresh) {
        return $routes;
    }
    $routes = M('route')->where(array('status' => 1))->order("sort asc")->select();
    $all_routes_s = array();  //静态路由
    $all_routes_d = array();  //规则路由
    $cache_routes = array();
    foreach ($routes as $route){
        $full_url = htmlspecialchars_decode($route['full_url']);
        // 解析URL
        $info = parse_url($full_url);
        $path = explode("/", $info['path']);
        if(count($path)!=3){ //必须是完整 url
            continue;
        }
        //$module=strtolower($path[0]);

        // 解析参数
        $vars = array();
        if(isset($info['query'])) { // 解析地址里面参数 合并到vars
            parse_str($info['query'], $params);
            $vars = array_merge($params, $vars);
        }
        //$vars_src=$vars;
        ksort($vars);
        $path=$info['path'];
        $full_url=$path . (empty($vars)? "":"?") . http_build_query($vars);
        //显示的url
        $url=$route['url'];
        if(strpos($url,':') ===false){
            //静态,不含动态参数
            $cache_routes['static'][$full_url] = $url;
            $all_routes_s[$url] = $full_url;
        }else{
            //动态
            $cache_routes['dynamic'][$path][]=array("query"=>$vars,"url"=>$url);
            $all_routes_d[$url]=$full_url;
        }
    }
    F('routes', $cache_routes);

    $route_dir = SITE_PATH . "/data/conf/";
    if (!file_exists($route_dir)) {
        FileUtil::mk_dir($route_dir);
    }

    $route_file = $route_dir . "route.php";

    file_put_contents($route_file, "<?php\r\n\treturn " . stripslashes(var_export(
        array(
            'URL_MAP_RULES' => $all_routes_s,
            'URL_ROUTE_RULES' => $all_routes_d
        ), true)) . ";");
    return $cache_routes;
}